<script setup lang="ts">
import type { DialogEvent, DialogProps } from './index'
import { Close, FullScreen } from '@element-plus/icons-vue'

const props = withDefaults(defineProps<DialogProps>(), {
  title: '提示',
  size: 'default',
  modal: true,
  closeOnClickModal: true,
  closeOnPressEscape: true,
  hideCancel: false,
  hideConfirm: false,
  confirmLoading: false,
  disabledConfirm: false,
})
const emits = defineEmits<DialogEvent>()
// 弹窗显示
let visible = $ref(false)
let title = $ref(props.title)
let dialogSize = $ref(props.size)
let fullScreen = $ref(dialogSize === 'full')
const configStore = useConfigStoreHook()
// 弹窗宽度
const dialogWidth = $computed(() => {
  if (dialogSize === 'full') {
    return '100%'
  }
  if (dialogSize === 'large') {
    return '98%'
  }
  if (dialogSize === 'medium') {
    return '60%'
  }
  if (dialogSize === 'small') {
    return '30%'
  }
  return '40%'
})
// 弹窗高度
const contentHeight = $computed(() => {
  if (fullScreen) {
    if (props.hideHeader && props.hideFooter) {
      return 97
    }
    if (props.hideHeader) {
      return 90
    }
    if (props.hideFooter) {
      return 92
    }
    return 86
  }
  if (!props.hideHeader && !props.hideFooter) {
    return 78
  }
  if (!props.hideFooter) {
    return 82
  }
  if (!props.hideHeader) {
    return 85
  }
  return 89
})

/**
 * 弹窗打开
 */
function openDialog<OnCloseResolveType>(arg: DialogOpenType): {
  dialogPrm: Promise<OnCloseResolveType>
  onCloseResolve: (arg: OnCloseResolveType) => void
} {
  visible = true
  if (arg.title) {
    title = arg.title
  }
  // 移动端默认全屏
  if (configStore.isMobile) {
    dialogSize = 'full'
    fullScreen = true
  }
  else {
    if (arg.size) {
      dialogSize = arg.size
      fullScreen = dialogSize === 'full'
    }
  }

  let onCloseResolve: ((arg: OnCloseResolveType) => void) | undefined
  const dialogPrm = new Promise<OnCloseResolveType>((resolve) => {
    onCloseResolve = function (arg: OnCloseResolveType) {
      visible = false
      resolve(arg)
    }
  })
  return { dialogPrm, onCloseResolve: onCloseResolve! }
}

/**
 * 弹窗关闭
 */
function closeDialog() {
  visible = false
}
// 确定
function confirm() {
  emits('confirm')
}
// 取消
async function cancel() {
  if (props.beforeClose === undefined) {
    closeDialog()
  }
  else {
    props.beforeClose?.(closeDialog)
  }
}

defineExpose({ closeDialog, openDialog })
</script>

<template>
  <el-dialog
    v-bind="{
      props,
      title: props.hideHeader ? '' : title,
    }"
    v-model="visible"
    :style="{
      borderRadius: fullScreen ? '0' : '',
    }"
    :class="{ 'hide-header': hideHeader }"
    :width="dialogWidth"
    :fullscreen="fullScreen"
    :show-close="false"
    append-to-body
    :top="`${dialogSize === 'large' ? 2 : 4}vh`"
  >
    <template #header="{ titleId, titleClass }">
      <slot v-if="!hideHeader" name="header" v-bind="{ cancel, titleId, titleClass }">
        <div class="header">
          <slot name="title" v-bind="{ cancel, titleId, titleClass }">
            <div :id="titleId" class="title" :class="titleClass">
              {{ hideTitle ? "" : title }}
            </div>
          </slot>
          <div class="operation">
            <div v-if="!hideFull" class="icon">
              <sy-icon
                v-if="fullScreen"
                icon="icon-park-outline:off-screen"
                @click="fullScreen = false"
              />
              <el-icon v-else @click="fullScreen = true">
                <FullScreen />
              </el-icon>
            </div>
            <div v-if="!hideClose" class="icon">
              <el-icon
                @click="cancel"
              >
                <Close />
              </el-icon>
            </div>
          </div>
        </div>
      </slot>
    </template>
    <template v-if="!hideFooter" #footer>
      <slot name="footer" v-bind="{ closeDialog }">
        <div class="divider" />
        <el-button
          v-if="!hideCancel"
          auto-insert-space
          @click="cancel"
        >
          取消
        </el-button>
        <el-button
          v-if="!hideConfirm"
          type="primary"
          auto-insert-space
          :loading="confirmLoading"
          :disabled="disabledConfirm"
          @click="confirm"
        >
          确认
        </el-button>
      </slot>
    </template>
    <el-scrollbar
      class="scrollbar"
      :max-height="`${dialogSize === 'large' ? contentHeight + 3 : contentHeight}vh`"
    >
      <slot name="default" />
    </el-scrollbar>
  </el-dialog>
</template>

<style scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  .title {
    font-size: 14px;
    color: var(--sy-text-color-secondary);
  }
  .operation {
    display: flex;
    font-size: 14px;
    gap: 10px;
    .icon {
      cursor: pointer;
      color: var(--sy-text-color-secondary);
      &:hover {
        color: var(--sy-color-primary);
      }
    }
  }
}
.divider {
  margin-bottom: 15px;
  border-bottom: 1px solid var(--sy-layout-border-color);
}
</style>

<style>
.hide-header {
  .sy-dialog__header {
    padding: 0 !important;
  }
}
.is-fullscreen {
  .sy-dialog__footer {
    position: absolute;
    left: 0;
    right: 15px;
    bottom: 15px;
  }
}

.sy-overlay-dialog {
  overflow: hidden !important;
}
</style>
